package com.dongnao.jack.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;

import com.alibaba.fastjson.JSONObject;
import com.dongnao.jack.invocate.bean.HttpInvocateParamBean;
import com.dongnao.jack.spring.parse.ServiceConfig;

/**
 * 
 * @ClassName: DispatcherServlet 
 * @Description: 用于接收 http请求
 * @author xuyp
 * @date 2018年4月26日 下午2:09:09 
 *
 */
public class DispatcherServlet extends HttpServlet {

    /** 
     * @Fields serialVersionUID : 
     */
    private static final long serialVersionUID = 4441960858843854935L;

    @SuppressWarnings("static-access")
    @Override
    public void service(ServletRequest req, ServletResponse res) {

        try {

            // 使用封装执行ben
            HttpInvocateParamBean paramBean = getParamBean(req, res);
            if (paramBean != null) {

                ApplicationContext context = ServiceConfig.applicationContext;
                Object bean = context.getBean(paramBean.getRef());
                Method method = getMethod(bean, paramBean.getMethodName(), paramBean.getArgs());
                Object result = method.invoke(bean, paramBean.getArgs());

                res.getWriter().print(result);

            }

            /*
             * 使用jsonobject
             * JSONObject jsonObject = getParamJsonBean(req, res);
            String ref = jsonObject.getString("ref");
            String methodName = jsonObject.getString("method");
            JSONArray argsArray = jsonObject.getJSONArray("args");
            Object[] args = new Object[argsArray.size()];
            int i = 0;
            for (Object object : args) {
                args[i] = argsArray.get(i);
            
                i++;
            }
            JSONArray parseArray = jsonObject.getJSONArray("paramTypes");
            
            ApplicationContext context = ServiceConfig.applicationContext;
            
            Object object = context.getBean(ref);
            Method method = getMethod(object, methodName, args);
            Object result = method.invoke(object, args);
            
            res.getWriter().print(result);*/

        }
        catch (Exception e) {
            try {
                res.getWriter().print("-----------error------------");
            }
            catch (IOException e1) {

                e1.printStackTrace();
            }
        }

    }

    private Method getMethod(Object object, String methodName, Object[] args) {

        Method[] methods = object.getClass().getMethods();
        for (Method method : methods) {

            if (method.getName().equals(methodName)) {

                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length == args.length) {

                    for (int i = 0; i < args.length; i++) {
                        Object object2 = args[i];
                        if (!object2.getClass().getName().equals(parameterTypes[i].getName())) {
                            return null;
                        }
                    }

                    return method;

                }

            }

        }

        return null;
    }

    private JSONObject getParamJsonBean(ServletRequest req, ServletResponse res) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream()));

        StringBuilder sb = new StringBuilder();
        String strLine = "";
        while ((strLine = br.readLine()) != null) {
            sb.append(strLine);
        }

        if (StringUtils.isNoneBlank(sb)) {
            // JSONObject jsonObject = JSONObject.parseObject(sb.toString());
            // String object = jsonObject.get("paramInvocation").toString();
            // Object parse = JSONObject.parse(sb.toString());
            // System.out.println(parse);

            // System.out.println(bean);
            // HttpInvocateParamBean parseObject = JSONObject.parseObject(parse.toString(),
            // HttpInvocateParamBean.class);
            return JSONObject.parseObject(sb.toString());

        }

        return null;

    }

    private HttpInvocateParamBean getParamBean(ServletRequest req, ServletResponse res) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream()));

        StringBuilder sb = new StringBuilder();
        String strLine = "";
        while ((strLine = br.readLine()) != null) {
            sb.append(strLine);
        }

        if (StringUtils.isNoneBlank(sb)) {
            // JSONObject jsonObject = JSONObject.parseObject(sb.toString());
            // String object = jsonObject.get("paramInvocation").toString();
            // Object parse = JSONObject.parse(sb.toString());
            // System.out.println(parse);
            HttpInvocateParamBean bean = JSONObject.parseObject(sb.toString(), HttpInvocateParamBean.class);
            // System.out.println(bean);
            // HttpInvocateParamBean parseObject = JSONObject.parseObject(parse.toString(),
            // HttpInvocateParamBean.class);
            return bean;
        }

        return null;

    }

}
